package tools

import (
	"bufio"
	"bytes"
	"encoding/json"
	"fmt"
	"io"
	"io/ioutil"
	"net/http"
	"os"
	"path/filepath"
	"strings"
)

func IsExist(fileAddr string) bool {
	// 读取文件信息，判断文件是否存在
	_, err := os.Stat(fileAddr)
	if err != nil {
		if os.IsExist(err) { // 根据错误类型进行判断
			return true
		}
		return false
	}
	return true
}

func GetAbsPath(path string) string {
	if filepath.IsAbs(path) {
		return path
	} else {
		absPath, _ := filepath.Abs(path)
		return absPath
	}
}

func MoveNginxConfigFile(path string, dstFile string) {
	filePath := filepath.Join(GetAbsPath(path), "nginx.conf")
	if IsExist(filePath) {
		// 存在
		CopyFile(dstFile, filePath)
	} else {
		// 不存在
	}
}

func CopyFile(dstName, srcName string) (written int64, err error) {
	src, err := os.Open(srcName)
	if err != nil {
		panic(err)
	}
	defer src.Close()
	dst, err := os.OpenFile(dstName, os.O_WRONLY|os.O_CREATE, 0644)
	if err != nil {
		panic(err)
	}
	defer dst.Close()
	return io.Copy(dst, src)
}

func FormatEnabled(status bool) string {
	if status {
		return "Enabled"
	} else {
		return "Disabled"
	}
}

func ResponseOk(writer http.ResponseWriter) {
	output, _ := json.Marshal(map[string]string{
		"Message": "Success",
	})
	writer.Write(output)
	writer.WriteHeader(http.StatusOK)
}

func ResponseError(writer http.ResponseWriter, err interface{}) {
	writer.WriteHeader(http.StatusInternalServerError)
	output, _ := json.Marshal(map[string]string{
		"Message": fmt.Sprintf("Error : %v", err),
	})
	writer.Write(output)
}

func FormatJson(bts []byte) string {
	var str bytes.Buffer
	_ = json.Indent(&str, bts, "", "    ")
	return str.String()
}

// 获取基础目录
func GetBasePath() string {
	homePath := os.Getenv("VALA_HOME")
	if homePath == "" {
		homePath = filepath.Dir(os.Args[0])
	}
	return homePath
}

func GetAdminPath() string {
	return filepath.Join(GetBasePath(), "admin")
}

func GetOutFile(name string) *os.File {
	file, _ := os.OpenFile(filepath.Join(GetBasePath(), name+"-output.log"), os.O_CREATE|os.O_RDWR, os.ModePerm)
	return file
}

// 启动进程
func StartProcess(execFile string, argv []string) (*os.Process, chan *os.ProcessState) {
	var error error
	env := os.Environ()
	file := GetOutFile("php")
	attr := &os.ProcAttr{
		Dir: filepath.Dir(execFile),
		Files: []*os.File{
			os.Stdin,
			file,
			file,
		},
		Env: env,
	}

	process, error := os.StartProcess(execFile, append([]string{filepath.Base(execFile)}, argv...), attr)
	if error != nil {
		panic(error)
	}
	var chanState = make(chan *os.ProcessState, 1)
	go func() {
		processState, error := process.Wait()
		if error != nil {
			panic(error)
		}
		chanState <- processState
	}()

	return process, chanState
}

func Cors(writer http.ResponseWriter) {
	writer.Header().Set("Access-Control-Allow-Origin", "*")             //允许访问所有域
	writer.Header().Add("Access-Control-Allow-Headers", "Content-Type") //header的类型
	writer.Header().Set("content-type", "application/json")
}

// 追加Hosts
func AppendHosts(serverName string) error {
	var hostsFile = "C:\\Windows\\System32\\drivers\\etc\\hosts"
	byt, _ := ioutil.ReadFile(hostsFile)

	return ioutil.WriteFile(
		hostsFile,
		[]byte(fmt.Sprintf("%s\n127.0.0.1\t%s", string(byt),
			serverName,
		)), os.ModePerm)
}

// 删除Hosts
func DeleteHosts(serverName string) error {
	var hostsFile = "C:\\Windows\\System32\\drivers\\etc\\hosts"
	file, _ := os.OpenFile(hostsFile, os.O_CREATE|os.O_RDWR, os.ModePerm)
	buffer := bytes.Buffer{}
	scanner := bufio.NewScanner(file)
	for scanner.Scan() {
		if !strings.Contains(scanner.Text(), serverName) {
			buffer.WriteString(fmt.Sprintf("%s\n", scanner.Text()))
		}
	}
	if error := scanner.Err(); error != nil {
		panic(error)
	}

	return ioutil.WriteFile(hostsFile, buffer.Bytes(), os.ModePerm)
}

func UpdateHosts(serverName string, newServerName string) error {
	var hostsFile = "C:\\Windows\\System32\\drivers\\etc\\hosts"
	file, _ := os.OpenFile(hostsFile, os.O_CREATE|os.O_RDWR, os.ModePerm)
	buffer := bytes.Buffer{}
	scanner := bufio.NewScanner(file)

	for scanner.Scan() {
		fmt.Println(scanner.Text())
		if !strings.Contains(scanner.Text(), serverName) {
			buffer.WriteString(fmt.Sprintf("%s\n", scanner.Text()))
		} else {
			buffer.WriteString(fmt.Sprintf("127.0.0.1\t%s\n", newServerName))
		}
	}

	return ioutil.WriteFile(hostsFile, buffer.Bytes(), os.ModePerm)
}
